package com.qjcc.util;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;


import com.qjcc.R;
import com.qjcc.app.AppContext;
import com.qjcc.bean.Update;
import com.qjcc.ui.IndexActivity;

import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 应用程序更新工具包
 */
public class UpdateManager {

    private static final int DOWN_NOSDCARD = 0;
    private static final int DOWN_UPDATE = 1;
    private static final int DOWN_OVER = 2;

    private static UpdateManager updateManager;

    private Context mContext;
    // 通知对话框
    private Dialog noticeDialog;
    // 下载对话框
    private Dialog downloadDialog;
    // 进度条
    private ProgressBar mProgress;
    // 查询动画
    private ProgressDialog mProDialog;

    private int progress;
    // 下载线程
    private Thread downLoadThread;
    // 终止标记
    private boolean interceptFlag = false;
    // 提示语
    private String updateMsg = "";
    // 返回的安装包url
    private String apkUrl = "";
    // 下载包保存路径
    private String savePath = "";
    // apk保存完整路径
    private String apkFilePath = "";

    private String curVersionName = "";

    private boolean isUpdateFlag = true;

    private int curVersionCode;
    //更新显示位置  1居中 2上  3左上  4左  5左下  6下 7右下 8右 9右上
    private static String gravity = "1";
    private Update mUpdate;

    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWN_UPDATE:
                    mProgress.setProgress(progress);
                    break;
                case DOWN_OVER:
                    downloadDialog.dismiss();
                    installApk();
                    break;
                case DOWN_NOSDCARD:
                    downloadDialog.dismiss();
                    Toast.makeText(mContext, mContext.getResources().getString(R.string.down_err_no_sdcard), Toast.LENGTH_LONG).show();
                    break;
            }
        }
    };
    private boolean cancelEnable = true;

    public static UpdateManager getUpdateManager() {
        if (updateManager == null) {
            updateManager = new UpdateManager();
        }
        return updateManager;
    }

    /**
     * 检查版本更新
     *
     * @param appContext
     * @return
     */
    public void checkVersion(final Context appContext, final boolean isShowMsg) throws Exception {

        String url = appContext.getString(R.string.apkCheckUpdateUrl);
        Map params = new HashMap();
        params.put("versionCode", curVersionCode + "");
        params.put("versionName", curVersionName + "");

        HttpAccessUtils.callHttpAccess(appContext, url, params, new HttpAccessUtils.HttpAccessCallBack() {
            @Override
            public void callBack(Object result) {
                Log.d("updateManager", result.toString());
                if (mProDialog != null) {
                    mProDialog.dismiss();
                }
                try {
                    JSONObject jsonObj = new JSONObject(result.toString());
                    String isUpdate = jsonObj.getString("isUpdate");
                    if ("1".equals(isUpdate)) {
                        gravity = jsonObj.getString("gravity");
                        mUpdate = Update.parseJsonObj(jsonObj);
                        if (mUpdate != null) {
                            apkUrl = mUpdate.getDownloadUrl();
                            updateMsg = mUpdate.getUpdateLog();
                            showNoticeDialog();
                        } else {
                            if (isShowMsg) {
                                showDialog(mContext, R.layout.layout_dialog_app, mContext.getResources().getString(R.string.sys_tip), mContext.getResources().getString(R.string.get_update_info_error) + "，详情：获取更新信息异常。", mContext.getResources().getString(R.string.ok), null, true, null);
                            }
                        }

                    } else {
                        if (isShowMsg) {
                            showDialog(mContext, R.layout.layout_dialog_app, mContext.getResources().getString(R.string.sys_tip), mContext.getResources().getString(R.string.latest_version), mContext.getResources().getString(R.string.ok), null, true, null);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if (isShowMsg) {
                        showDialog(mContext, R.layout.layout_dialog_app, mContext.getResources().getString(R.string.sys_tip), mContext.getResources().getString(R.string.get_update_info_error) + "，详情：" + e.getMessage(), mContext.getResources().getString(R.string.ok), null, true, null);
                    }
                }


            }

        });
    }

    /**
     * 检查App更新
     *
     * @param context
     * @param isShowMsg     是否显示提示消息
     * @param isFouceUpdate 是否强制显示更新
     */

    public void checkAppUpdate(Context context, final boolean isShowMsg, final boolean isFouceUpdate) {

        if (isUpdateFlag || isFouceUpdate) {
            this.mContext = context;
            getCurrentVersion();
            if (isShowMsg) {
                mProDialog = ProgressDialog.show(mContext, null, mContext.getResources().getString(R.string.checking_wait),
                        true, true);
            }
            try {
                checkVersion(mContext
                        .getApplicationContext(), isShowMsg);
            } catch (Exception e) {
                e.printStackTrace();
                if (isShowMsg)
                    showDialog(mContext, R.layout.layout_dialog_app, mContext.getResources().getString(R.string.sys_tip), mContext.getResources().getString(R.string.get_update_info_error) + "，详情：" + e.getMessage(), mContext.getResources().getString(R.string.ok), null, true, null);
            }


//            final Handler handler = new Handler() {
//                public void handleMessage(Message msg) {
//                    if (isShowMsg && mProDialog != null)
//                        mProDialog.dismiss();
//                    if (msg.what == 1) {
//                        mUpdate = (Update) msg.obj;
//                        if (mUpdate != null) {
//                            if (curVersionCode < mUpdate.getVersionCode()) {
//                                apkUrl = mUpdate.getDownloadUrl();
//                                updateMsg = mUpdate.getUpdateLog();
//                                showNoticeDialog();
//                            } else if (isShowMsg) {
//                                showDialog(mContext,R.layout.layout_dialog_app, mContext.getResources().getString(R.string.sys_tip), mContext.getResources().getString(R.string.latest_version), mContext.getResources().getString(R.string.ok), null,true, null);
//                            }
//                        }
//                    } else if (isShowMsg) {
//                        showDialog(mContext,R.layout.layout_dialog_app,  mContext.getResources().getString(R.string.sys_tip), mContext.getResources().getString(R.string.get_update_info_error), mContext.getResources().getString(R.string.ok), null ,true,null);
//                    }
//                }
//            };
//            new Thread() {
//                public void run() {
//                    Message msg = new Message();
//                    try {
//
//                        Update update = checkVersion((AppContext) mContext
//                                .getApplicationContext());
//                        msg.what = 1;
//                        msg.obj = update;
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    handler.sendMessage(msg);
//                }
//            }.start();
        }

    }

    /**
     * 获取当前客户端版本信息
     */
    private void getCurrentVersion() {
        try {
            PackageInfo info = mContext.getPackageManager().getPackageInfo(
                    mContext.getPackageName(), 0);
            curVersionName = info.versionName;
            curVersionCode = info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace(System.err);
        }
    }

    /**
     * 显示版本更新通知对话框
     */
    private void showNoticeDialog() {
        String title = mContext.getResources().getString(R.string.version_update) + curVersionName + " > " + mUpdate.getVersionName();
        String cancel = null;
        //重大版本是否强制更新
        cancelEnable = true;
        if ("0".equals(mUpdate.getForceUpdate())) {
            cancel = mContext.getString(R.string.download_later);
        } else {
            cancelEnable = false;
            //强制更新时，点击弹出框其它区域直接退出程序
//			builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
//				@Override
//				public void onDismiss(DialogInterface dialog) {
//					AppManager.getAppManager().AppExit(mContext);
//				}
//			});

        }

        showDialog(mContext, R.layout.layout_dialog_app, title, updateMsg, mContext.getString(R.string.download_now), cancel, cancelEnable, new DialogCallback() {
            @Override
            public void confirmCallBack() {
                //判断当前手机的网络连接，如果是流量，需要提示用户
                if (!NetWorkUtil.isWifi(mContext)) {
                    showDialog((Activity) mContext, R.layout.layout_dialog_app, mContext.getString(R.string.tip), mContext.getString(R.string.data_download_tip), "确定", "取消", cancelEnable, new DialogCallback() {
                        @Override
                        public void confirmCallBack() {
                            showDownloadDialog();
                        }

                        @Override
                        public void cancelCallBack() {
                            isUpdateFlag = false;
                            if ("1".equals(mUpdate.getForceUpdate())) {
                                showNoticeDialog();
                            }
                        }
                    });
                } else {
                    showDownloadDialog();
                }

            }

            @Override
            public void cancelCallBack() {
                isUpdateFlag = false;
            }
        });
    }

    /**
     * 显示下载对话框
     */
    private void showDownloadDialog() {
        Builder builder = new Builder(mContext);
        builder.setTitle(mContext.getResources().getString(R.string.downloading_new_version));

        final LayoutInflater inflater = LayoutInflater.from(mContext);
        View v = inflater.inflate(R.layout.update_progress, null);
        mProgress = (ProgressBar) v.findViewById(R.id.update_progress);

        builder.setView(v);
        builder.setCancelable(false);
        builder.setNegativeButton(mContext.getResources().getString(R.string.cancel), new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                interceptFlag = true;
                isUpdateFlag = false;
                if ("1".equals(mUpdate.getForceUpdate())) {
                    killDownloadApk();
                    System.exit(0);
                }
            }
        });
        downloadDialog = builder.create();
        downloadDialog.show();

        downloadApk();
    }

    private Runnable mdownApkRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                String apkName = "yktapp_" + mUpdate.getVersionName()
                        + ".apk";
                // 判断是否挂载了SD卡
                String storageState = Environment.getExternalStorageState();
                if (storageState.equals(Environment.MEDIA_MOUNTED)) {
                    savePath = Environment.getExternalStorageDirectory()
                            .getAbsolutePath() + "/yktapp/Update/";
                    File file = new File(savePath);
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    apkFilePath = savePath + apkName;
                }

                // 没有挂载SD卡，无法下载文件
                if (apkFilePath == null || apkFilePath == "") {
                    mHandler.sendEmptyMessage(DOWN_NOSDCARD);
                    return;
                }

                File ApkFile = new File(apkFilePath);

//				// 是否已下载更新文件
//				if (ApkFile.exists()) {
//					
//					downloadDialog.dismiss();
//					installApk();
//					return;
//				}

                FileOutputStream fos = new FileOutputStream(ApkFile);

                URL url = new URL(apkUrl);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                /**
                 *   在默认情况下，HttpURLConnection 使用 gzip方式获取，文件 getContentLength()这个方法，
                 *   每次read完成后可以获得，当前已经传送了多少数据，而不能用这个方法获取 需要传送多少字节的内容，
                 *   当read() 返回 -1时，读取完成，由于这个压缩后的总长度我无法获取，那么进度条就没法计算值了。
                 要取得长度则，要求http请求不要gzip压缩。。。
                 为了防止conn.getContentLength();返回-1，加上这段代码
                 */
                conn.setRequestProperty("Accept-Encoding", "identity");
                conn.connect();

                int length = conn.getContentLength();
                InputStream is = conn.getInputStream();

                int count = 0;
                byte buf[] = new byte[1024];

                do {
                    int numread = is.read(buf);
                    count += numread;
//                    Log.e("progress------count","numread="+numread+"          count="+count+"              length="+length+"---------------------------");
                    progress = (int) (((float) count / length) * 100);
                    // 更新进度
                    mHandler.sendEmptyMessage(DOWN_UPDATE);
                    if (numread <= 0) {
                        // 下载完成通知安装
                        mHandler.sendEmptyMessage(DOWN_OVER);
                        break;
                    }
                    fos.write(buf, 0, numread);
                } while (!interceptFlag);// 点击取消就停止下载

                //循环完成后设置取消变量为默认，否则取消后就下载不了了
                interceptFlag = false;
                fos.close();
                is.close();
            } catch (MalformedURLException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }
    };

    /**
     * 下载apk
     */
    private void downloadApk() {
        downLoadThread = new Thread(mdownApkRunnable);
        downLoadThread.start();
    }

    /**
     * 挂起下载进程
     */
    private void killDownloadApk() {
        if (downLoadThread != null && downLoadThread.isAlive()) {
            downLoadThread.interrupt();
        }
    }

    /**
     * 安装apk
     */
    private void installApk() {
        File apkfile = new File(apkFilePath);
        if (!apkfile.exists()) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri uri = FileProvider.getUriForFile(mContext,
                    "com.qjcc.fileProvider",
                    apkfile);
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setDataAndType(uri, "application/vnd.android.package-archive");
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            mContext.startActivity(i);
        } else {
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
                    "application/vnd.android.package-archive");
            mContext.startActivity(i);
        }
        if ("1".equals(mUpdate.getForceUpdate())) {
            System.exit(0);
        }
    }


    /**
     * 自定义提示信息对话框(可自定义确定、取消按钮文字，可设置是否能取消)
     * 单按钮的只设置一个值，回调对应设置的按钮
     *
     * @param context
     * @param title
     * @param message
     * @param submitButton
     * @param cancelButton
     * @param cancelEnable
     * @param callback
     */
    public static void showDialog(Context context, int layoutResId, String title, String message, String submitButton, String cancelButton, boolean cancelEnable, final DialogCallback callback) {
        View view = LayoutInflater.from(context).inflate(layoutResId, null);
        TextView titleText = (TextView) view.findViewById(R.id.title);
        if (isEmpty(title, false)) {
            ((View) titleText.getParent()).setVisibility(View.GONE);
        } else {
            titleText.setText(title);
        }
        TextView messageText = (TextView) view.findViewById(R.id.message);
//        message = message.replaceAll("\t","");
        if (isEmpty(message, false)) {
            messageText.setVisibility(View.GONE);
        } else {
            messageText.setText(message);
        }

        final Dialog dialog = new Dialog(context);
        Window window = dialog.getWindow();
        window.setBackgroundDrawable(new BitmapDrawable());
        window.requestFeature(Window.FEATURE_NO_TITLE);
        try {
            int gravityInt = Integer.valueOf(gravity);
            switch (gravityInt) {
                case 1:
                    window.setGravity(Gravity.CENTER);
                    break;
                case 2:
                    window.setGravity(Gravity.TOP);
                    break;
                case 3:
                    window.setGravity(Gravity.TOP | Gravity.LEFT);
                    break;
                case 4:
                    window.setGravity(Gravity.LEFT);
                    break;
                case 5:
                    window.setGravity(Gravity.LEFT | Gravity.BOTTOM);
                    break;
                case 6:
                    window.setGravity(Gravity.BOTTOM);
                    break;
                case 7:
                    window.setGravity(Gravity.BOTTOM | Gravity.RIGHT);
                    break;
                case 8:
                    window.setGravity(Gravity.RIGHT);
                    break;
                case 9:
                    window.setGravity(Gravity.TOP | Gravity.RIGHT);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

//        window .setGravity(Gravity.CENTER);
        dialog.setContentView(view);
        dialog.setCancelable(cancelEnable);
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        window.getAttributes().width = wm.getDefaultDisplay().getWidth() / 5 * 4;
        dialog.show();

        Button submit = (Button) view.findViewById(R.id.submit);
        if (isEmpty(submitButton, false)) {
            submit.setVisibility(View.GONE);
        } else {
            submit.setText(submitButton);
        }
        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (callback != null) {
                    callback.confirmCallBack();
                }
                if (dialog != null) {
                    dialog.dismiss();
                }
            }
        });
        Button cancel = (Button) view.findViewById(R.id.cancel);
        if (isEmpty(cancelButton, false)) {
            cancel.setVisibility(View.GONE);
        } else {
            cancel.setText(cancelButton);
        }
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (callback != null) {
                    callback.cancelCallBack();
                }
                if (dialog != null) {
                    dialog.dismiss();
                }
            }
        });

    }


    /**
     * 对话框点击按钮回调接口
     */
    public interface DialogCallback {
        /**
         * 确定按钮回调方法
         */
        public void confirmCallBack();

        /**
         * 取消按钮的回调方法
         */
        public void cancelCallBack();

    }

    /**
     * 判断给定字符串是否空白串。
     * 空白串是指由空格、制表符、回车符、换行符组成的字符串
     * 若输入字符串为null或空字符串，返回true
     *
     * @param input
     * @param nullStringIsEmpty "null"是否判断为空
     * @return
     */
    public static boolean isEmpty(String input, boolean nullStringIsEmpty) {
        if (input == null || "".equals(input))
            return true;
        if (nullStringIsEmpty && "null".equals(input.toLowerCase()))
            return true;

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                return false;
            }
        }
        return true;
    }

}
